/****************************************************************************
 *
 *  ALi (Shanghai) Corporation, All Rights Reserved. 2007 Copyright (C)
 *
 *  File: m3329c_audio.c
 *
 *  Description: This file describes m3329c audio driver operations.
 *
 *  History:
 *      Date        	Author      	Version  		Comment
 *      ====        	======      =======  	=======
 *  1.  2007.5.22  Martin_Xia  	0.0.1  		
 *
 ****************************************************************************/



#include <types.h>

#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/deca/deca_dev.h>
#include <hld/deca/deca.h>
#include <hld/snd/snd_dev.h>
#include <hld/snd/snd.h>

#include <api/libmp/pe.h>
#include "m3329c.h"



/**********************External  Variables***********************************/
extern struct snd_device						*snd_dev ;
extern struct deca_device						*deca_dev;




/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_can_decode
//
// Description:
//	To judge the decoder supportted the song or not 
//
// Arguments:
//	IN  MusicType type				Music type
//	IN  void *param					Parameter depends on the music type
//
// Return Value:
//	RET_CODE
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_can_decode(MusicType type, void *param)
{
	
	switch (type)
	{
		case Mp3:
		{
			return deca_io_control(deca_dev, DECA_MP3_CAN_DECODE,  (UINT32)param);
		}
		default:
		{
			return RET_FAILURE;
		}
	}

}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_get_frame_info
//
// Description:
//	To the information of music frames from the decoder 
//
// Arguments:
//	IN  MusicType type				Music type
//	IN  void *param					Parameter depends on the music type
//
// Return Value:
//	RET_CODE
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_get_frame_info(MusicType type, void *param)
{
	switch (type)
	{
		case Mp3:
		{
			return deca_io_control(deca_dev, DECA_GET_AUDIO_INFO,  (UINT32)param);
		}
		default:
		{
			return RET_FAILURE;
		}
	}

}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_get_volume
//
// Description:
//	To get the volume
//
// Arguments:
//  None
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////

void m3329c_audio_output_plugin_get_volume()
{
	//todo
	return;
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_set_volume
//
// Description:
//	To get the volume
//
// Arguments:
//  None
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////

void m3329c_audio_output_plugin_set_volume()
{
	//todo
	return;
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_open
//
// Description:
//	To init the decoder 
//
// Arguments:
//	IN  MusicType type				Music type
//
// Return Value:
//	-1								Unsuccessful
//   1								Success
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_open(MusicType type)
{
	switch (type)
	{
		case Mp3:
		{
			deca_io_control(deca_dev, DECA_SOFTDEC_INIT, 0);
			break;
		}
		default:
		{
			return -1;
		}
	}

	return 1;

}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_polling_write
//
// Description:
//	To use polling write to the decoder
//
// Arguments:
//	OUT void **data								Data buffer
//	IN  int requested_length					Requested buffer length for data buffer
//  OUT UINT32 *length							Actual allocated buffer length 
//
// Return Value:
//	RET_CODE
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_polling_write(void **data, int requested_length, UINT32 *length)
{
	struct control_block						control_block;

	MEMSET(&control_block, 0, sizeof(struct control_block));
	control_block.ctrlblk_valid = 1;

	return deca_request_write(deca_dev, requested_length, data, length, &control_block);
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_push_write
//
// Description:
//	To use push write to the decoder
//
// Arguments:
//	IN  void *ptr 					Data buffer
//	IN  int length					The length of data buffer
//
// Return Value:
//	RET_CODE
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_push_write(void *ptr, int length)
{
	//todo
	return 1;
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_polling_write_update
//
// Description:
//	To tell the decoder which uses polling write the data is ready
//
// Arguments:
//	IN  MusicType type				Music type
//	IN  void *param					Parameter depends on the music type
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////

void m3329c_audio_output_plugin_polling_write_update(int length)
{
	deca_update_write(deca_dev, length);
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_close
//
// Description:
//	To close the decoder 
//
// Arguments:
//	IN  MusicType type				Music type
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////

void m3329c_audio_output_plugin_close(MusicType type, BOOL stop_imm)
{
	switch (type)
	{
		case Mp3:
		{
			deca_io_control(deca_dev, DECA_SOFTDEC_CLOSE, stop_imm);
			break;
		}
		default:
		{
			return ;
		}
	}

	
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_flush
//
// Description:
//	TBD
//
// Arguments:
//	TBD
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_flush(MusicType type, int time)
{
	switch (type)
	{
		case Mp3:
		{
			return deca_io_control(deca_dev, DECA_SOFTDEC_JUMP_TIME, (unsigned long)time);
		}
		default:
		{
			return RET_FAILURE;
		}
	}

}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_pause
//
// Description:
//	To pause/resume the decoder 
//
// Arguments:
//	IN  BOOl p						Paused or not
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////

void m3329c_audio_output_plugin_pause(BOOL p)
{
	if (p)
	{
		deca_pause(deca_dev);
	}
	else
	{
		deca_start(deca_dev, 0);
	}
	return;
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_free
//
// Description:
//	TBD
//
// Arguments:
//	TBD
//
// Return Value:
//	TBD
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_free()
{
	//todo
	return 1;
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_playing
//
// Description:
//	To know the decoder is working or not 
//
// Arguments:
//	TBD
//
// Return Value:
//	TBD
//
/////////////////////////////////////////////////////////////////////////////

int m3329c_audio_output_plugin_playing()
{
	if (deca_io_control(deca_dev, DECA_SOFTDEC_IS_PLAY_END , 0) == RET_SUCCESS)
	{
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_get_output_time
//
// Description:
//	To get the playing time frome decoder 
//
// Arguments:
//  TBD
//
// Return Value:
//	time
//
/////////////////////////////////////////////////////////////////////////////

unsigned long m3329c_audio_output_plugin_set_time(MusicType type, int time)
{
	switch (type)
	{
		case Mp3:
		{
			return deca_io_control(deca_dev, DECA_SOFTDEC_SET_TIME , (unsigned long)time);
		}
		default:
		{
			return -1;
		}
	}

}

/////////////////////////////////////////////////////////////////////////////
// m3329c_audio_output_plugin_get_written_time
//
// Description:
//	To the elapse time from the decoder 
//
// Arguments:
//	IN  MusicType type				Music type
//
// Return Value:
//   -1								Unsuccessful
//	time							Elapse time
//
/////////////////////////////////////////////////////////////////////////////

unsigned long m3329c_audio_output_plugin_get_written_time(MusicType type)
{
	unsigned long 				time = -1;
	
	switch (type)
	{
		case Mp3:
		{
			if (deca_io_control(deca_dev, DECA_MP3_GET_ELAPSE_TIME , (unsigned long)&time) != RET_SUCCESS)
			{
				time = -1;
			}
			break;
		}
		default:
		{
			return -1;
		}
	}

	
	return time;
}

